/* Copyright ©, 2022, ECARX (Hubei) Technology Co., Ltd. All rights reserved.
 *
 * NOTICE: This file contains information which is confidential and proprietary to ECARX
 * (Hubei) Technology Co., Ltd. and/or other developers. No license to any intellectual
 * property rights contained within this file is either granted or implied except as may be
 * provided in an agreement with ECARX (Hubei) Technology Co., Ltd.
 *
 * Any unauthorized copying or distribution of content from this file in whole or in part
 * is prohibited.
 */
#ifndef ECARX_VHAL_CORE_VENDOR_SERVER_IMPL_H
#define ECARX_VHAL_CORE_VENDOR_SERVER_IMPL_H

#include <transfer/ITransfer.h>
#include <utils/Looper.h>

#include <unordered_map>

#include "property/IPropertyTransfer.h"
#include "vhal_core/Common.h"
#include <IVendorVehicleServer.h>
#include "vhal_core/persist/DID.h"
#include "vhal_core/persist/PlatformProfile.h"
#include "vhal_core/property/IProperty.h"

namespace ecarx::vhal::core::impl {

enum class RunMode { AOSP, DEBUG };

enum class Action { SET = 1, PROFILE_RESTORE, INIT_RESTORE, SIGNAL_RECEIVE };

template <typename T>
struct QueueTask {
    Action action;
    std::vector<T> data;
    int64_t flag;
};
class VendorVehicleServer : public property::IPropertyTransfer,
                            public interface::IVendorVehicleServer,
                            public persist::ProfileListener {
  private:
    RunMode mRunMode;
    //与属性Id关联的Property
    std::unordered_map<int32_t, property::IProperty*> propertyMap;
    //与信号关联的执行单元组 key 是信号 value是关心信号的单元集合
    std::unordered_map<int32_t, std::vector<property::Area*>> signalToAreas;
    std::map<RecordId, std::vector<std::function<void(const VehiclePropValue& value)>>>
        propChangeCallbacks;
    //用于Profile恢复的时候需要执行的任务单元
    std::vector<property::Area*> mRestoreAreas;

    HalServerCommit _mCallback;

    //存储PropertyConfig
    std::vector<interface::ConfigDeclaration> configs;
    std::vector<std::shared_ptr<ecarx::transfer::ITransfer>> mTransfers;
    persist::PlatformProfile* mPlatformProfile = nullptr;
    persist::DID* mDID = nullptr;

    VehiclePropValue notAvailableProperty;
    std::function<void()> mTransferReadyCallback = nullptr;

  public:
    VendorVehicleServer();
    ~VendorVehicleServer();
    bool addProperty(property::IProperty* property);
    void onSignalReceiver(const QueueTask<int32_t>&);
    void onSetFunctionTask(const QueueTask<VehiclePropValue>&);

    const property::IProperty* getProperty(int32_t propertyId) const;

    void onSignalChanged(const std::vector<int32_t>& changed);

    void setTransfers(const std::vector<std::shared_ptr<ecarx::transfer::ITransfer>>& transfers);
    void setPlatformProfile(persist::PlatformProfile* platformProfile);
    void setDID(persist::DID* did);

    void openTransfers(std::function<void()>&& transferReadyCb = nullptr);
    void onTransferReady(ecarx::transfer::NetState state);
    void initAllProperties();
    RunMode getRunMode();
    void setRunMode(RunMode mode);

    // impl  vendor::vhal::impl::VendorImpl
    std::vector<interface::ConfigDeclaration> onGetAllPropertyConfig() const override;
    void onSetProperty(const VehiclePropValue&) override;
    bool isSupported(int32_t propId) override;
    void registerUpdateCallback(const HalServerCommit&& callback) override;
    bool dump(const int fd,
              const android::hardware::hidl_vec<android::hardware::hidl_string>& options) override;

    // impl transfer::IPropertyTransfer
    std::unique_ptr<VehiclePropValue> getPropValue(int32_t propertyId, int32_t areaId) override;
    bool setPropValue(const VehiclePropValue& value) override;
    void onPropertyValue(const VehiclePropValue&,CommitMode) override;
    property::Area* findArea(int32_t propertyId, int32_t areaId) override;
    
    // impl persist::ProfileListener
    void onSwitchProfile(persist::Profile* lastProfile, persist::Profile* currentProfile) override;
};

}  // namespace ecarx::vhal::core::impl

#endif
